const init_args = () => {
    const args = {};
    process.argv.forEach(arg => {
        const kv = arg.split('=');
        if (kv.length === 2 && kv[1] !== '') {
            args[kv[0]] = kv[1];
        }
    });
    return args;
};

function is_type_of(t, arg) {
    switch (t) {
        case 'string':
        case 'boolean': {
            return typeof arg === t;
        }
        default: {
            if (t.endsWith('[]')) {
                if (!Array.isArray(arg)) { return false; }
                t = t.slice(0, -('[]'.length));
                for (let i = 0; i < arg.length; i++) {
                    if (!is_type_of(t, arg[i])) { return false; }
                }
                return true;
            }
            throw new Error('not implemented.');
        }
    }
}

function in_range(range, arg) {
    if (!Array.isArray(range)) { return true; }
    if (range.length === 0) { return true; }
    if (range.includes(arg)) { return true; }
    return false;
}

export const ARG_CONVERTERS = {
    'string': v => v,
    'boolean': v => v === 'true',
    'string[]': v => v.split(','),
};

/**
 * 处理命令参数
 * @param {object} configs 参数配置对象
 * @returns 参数对象
 */
export const handleArgs = (configs, args) => {
    if (typeof args !== 'object') { args = init_args(); }
    if (typeof configs !== 'object') { return args; }

    const result = {};
    Object.keys(configs).forEach(key => {
        const config = configs[key];

        if (Object.prototype.hasOwnProperty.call(args, key)) {
            const arg = args[key];

            if (typeof config.converter !== 'function') {// 没有设置转换器，或转换器类型错误时，设置默认转换器。
                config.converter = ARG_CONVERTERS[config.t];
            }

            if (is_type_of(config.t, arg)) {// 参数值与设置的类型一致时
                if (arg === '') {// 有key无value的情况 config.t === 'string' 字符串类型特殊处理
                    if (Object.prototype.hasOwnProperty.call(config, 'defaultValue')) {
                        result[key] = config.defaultValue;// 有默认值则设置默认值
                    } else {
                        return;// 无默认值则直接返回
                    }
                } else {// 其它类型，其它值，直接赋值。
                    result[key] = arg;
                }
            } else {// 参数值与设置的类型不一致时
                if (arg === '') {// 有key无value的情况
                    if (Object.prototype.hasOwnProperty.call(config, 'defaultValue')) {
                        result[key] = config.defaultValue;// 有默认值则设置默认值
                    } else {// 无默认值
                        if (in_range(config.range, arg)) {
                            result[key] = arg;// 取值范围内，设置该值。
                            return;
                        } else {
                            return;// 取值范围外，忽略该值。
                        }
                    }
                } else {// 有值
                    result[key] = config.converter(arg);// 设置转换值
                    if (!is_type_of(config.t, result[key])) {// 转换结果类型有误，不应该出现。
                        throw new Error('type error.');
                    }
                }
            }
        } else {
            if (Object.prototype.hasOwnProperty.call(config, 'defaultValue')) {
                result[key] = config.defaultValue;
            }
        }

        if (!in_range(config.range, result[key])) {
            throw new Error(`value <${result[key]}> is not within the range of valid values [${config.range}]`);
        }
    });
    return result;
};
